multer-rs
An async parser for multipart/form-data
content-type in Rust.
It accepts a Stream
of Bytes
as
a source, so that It can be plugged into any async Rust environment e.g. any async server.
Docs
Install
Add this to your Cargo.toml
:
[dependencies]
multer = "2.0"
Basic Example
use bytes::Bytes;
use futures::stream::Stream;
use multer::Multipart;
use std::convert::Infallible;
use futures::stream::once;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (stream, boundary) = get_byte_stream_from_somewhere().await;
let mut multipart = Multipart::new(stream, boundary);
while let Some(mut field) = multipart.next_field().await? {
let name = field.name();
let file_name = field.file_name();
println!("Name: {:?}, File Name: {:?}", name, file_name);
while let Some(chunk) = field.chunk().await? {
println!("Chunk: {:?}", chunk);
}
}
Ok(())
}
async fn get_byte_stream_from_somewhere() -> (impl Stream<Item = Result<Bytes, Infallible>>, &'static str) {
let data = "--X-BOUNDARY\r\nContent-Disposition: form-data; name=\"my_text_field\"\r\n\r\nabcd\r\n--X-BOUNDARY--\r\n";
let stream = once(async move { Result::<Bytes, Infallible>::Ok(Bytes::from(data)) });
(stream, "X-BOUNDARY")
}
Prevent Denial of Service (DoS) Attacks
This crate also provides some APIs to prevent potential DoS attacks with fine grained control. It's recommended to add some constraints
on field (specially text field) size to prevent DoS attacks exhausting the server's memory.
An example:
use multer::{Multipart, Constraints, SizeLimit};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let constraints = Constraints::new()
.allowed_fields(vec!["my_text_field", "my_file_field"])
.size_limit(
SizeLimit::new()
.whole_stream(15 * 1024 * 1024)
.per_field(10 * 1024 * 1024)
.for_field("my_text_field", 30 * 1024),
);
let mut multipart = Multipart::with_constraints(some_stream, "X-BOUNDARY", constraints);
while let Some(field) = multipart.next_field().await.unwrap() {
let content = field.text().await.unwrap();
assert_eq!(content, "abcd");
}
Ok(())
}
Usage with hyper.rs server
An example showing usage with hyper.rs.
For more examples, please visit examples.
Contributing
Your PRs and suggestions are always welcome.